using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DotVVM.Framework.ViewModel;
using VOICeVIO.Hybrid.Models;
using VOICeVIO.Hybrid.Services;

namespace VOICeVIO.Hybrid.ViewModels
{
    public class DownloadViewModel : MasterPageViewModel
    {
        public static List<Guid> Jobs = new List<Guid>();
        [Bind(Direction.ServerToClient)]
        public bool IsProcessing { get; set; } = true;
        public string Uid { get; set; }
        [Bind(Direction.ServerToClient)]
        public string ProcessState { get; set; } = "Now processing...";
        public string SongName { get; set; }
        private string _ccsPath = "ccs";
        private SvssService _svssService;
        private HybridService _hybridService;
        public DownloadViewModel(SvssService svssService, HybridService hybridService)
        {
            _svssService = svssService;
            _hybridService = hybridService;
        }

        public override async Task PreRender()
        {
            if (!Context.Parameters.ContainsKey("Id"))
            {
                Context.RedirectToRoute("Default");
            }
            Uid = Context.Parameters["Id"].ToString();
            if (Context.Parameters.ContainsKey("Name"))
            {
                SongName = Context.Parameters["Name"].ToString();
            }
            await base.PreRender();
        }

        public async Task Download()
        {
            ProcessState = "Processing...";
            IsProcessing = true;
            var song = await _hybridService.GetSongByUidAsync(Uid);
            if (song == null)
            {
                ProcessState = "Can not find project with corresponding ID.";
                return;
            }
            var guid = Guid.Parse(Uid);

            var fs = _svssService.GetWave(guid);
            if (fs == null)
            {
                var projectPath = Path.Combine(_ccsPath, Uid + ".ccs");
                if (!File.Exists(projectPath))
                {
                    ProcessState = "Failed! Project file not found.";
                    return;
                }

                if (Jobs.Contains(guid))
                {
                    ProcessState = "Failed! The last process is not finished.";
                    return;
                }
                Jobs.Add(guid);
                (var result, var info) = await _svssService.Synth(song.Singer, projectPath, guid, song.Volume);
                Jobs.Remove(guid);
                if (!result)
                {
                    ProcessState = $"Failed! Error: {info}";
                    return;
                }
                fs = _svssService.GetWave(guid);
            }

            if (fs == null)
            {
                ProcessState = "Failed! Wave file not found.";
                return;
            }

            ProcessState = "Succeed.";
            IsProcessing = false;

            var fileName = SongName;
            if (!SongName.IsASCII())
            {
                fileName = "VOICeVIO - HYBRID";
            }
            Context.ReturnFile(fs, fileName + ".wav", "audio/x-wav");
        }
    }
}
